#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dbus/dbus.h>

static int count = 0;

void handle_get_count(DBusMessage *msg, DBusConnection *conn) {
    DBusMessage *reply;
    reply = dbus_message_new_method_return(msg);
    dbus_message_append_args(reply, DBUS_TYPE_INT32, &count, DBUS_TYPE_INVALID);
    dbus_connection_send(conn, reply, NULL);
    dbus_message_unref(reply);
}

void handle_increment(DBusMessage *msg, DBusConnection *conn) {
    int value;
    dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &value, DBUS_TYPE_INVALID);
    count += value;

    DBusMessage *reply;
    reply = dbus_message_new_method_return(msg);
    dbus_connection_send(conn, reply, NULL);
    dbus_message_unref(reply);
}

int main() {
    DBusConnection *conn;
    DBusError err;

    dbus_error_init(&err);
    conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
    if (dbus_error_is_set(&err)) {
        fprintf(stderr, "Connection Error (%s)\n", err.message);
        dbus_error_free(&err);
        return 1;
    }

    dbus_bus_request_name(conn, "com.example.Counter", DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
    if (dbus_error_is_set(&err)) {
        fprintf(stderr, "Name Error (%s)\n", err.message);
        dbus_error_free(&err);
        return 1;
    }

    while (1) {
        dbus_connection_read_write(conn, 0);
        DBusMessage *msg = dbus_connection_pop_message(conn);
        if (msg == NULL) {
            continue;
        }

        if (dbus_message_is_method_call(msg, "com.example.Counter", "get_count")) {
            handle_get_count(msg, conn);
        } else if (dbus_message_is_method_call(msg, "com.example.Counter", "increment")) {
            handle_increment(msg, conn);
        }

        dbus_message_unref(msg);
    }

    return 0;
}

/*
gcc -o counter_service counter_service.c -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -ldbus-1
gcc -o counter_client counter_client.c -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -ldbus-1
*/
